package com.firmiana.jt809.netty.main;

import com.firmiana.jt809.config.GlobalConfig;
import com.firmiana.jt809.entity.JT809Message;
import com.firmiana.jt809.protocol.IReceiveProtocol;
import com.firmiana.jt809.util.SpringUtils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

/**
 * @author hucl
 * @date 2020/8/25 16:03
 */
@Slf4j
public class MainLinkHandler extends SimpleChannelInboundHandler<JT809Message> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, JT809Message msg) throws Exception {
        Channel channel = ctx.channel();
        // 业务类型
        int msgType = msg.getMsgType();
        // 平台id
        long platformId = msg.getMsgGNSSCenterID();
        log.info("【主链路】收到下级平台(" + platformId + ")上报报文类型0x" + Integer.toHexString(msgType) + "的信息！");

        Class<? extends IReceiveProtocol> handleClazz = GlobalConfig.getReceiveProtocolByProtocolId(msgType);
        if (handleClazz != null) {
            IReceiveProtocol protocol = SpringUtils.getBean(handleClazz);
            if (protocol == null) {
                log.warn("【主链路】没找到对应的业务类型处理类, 业务类型:[{}], 平台Id=[{}]", msgType, platformId);
                return;
            }
            String result = protocol.handle(msg);
            try {
                if (!StringUtils.isEmpty(result)) {
                    log.info("【主链路】 0x" + Integer.toHexString(msgType) + "应答(" + platformId + ")报文：" + result);
                    channel.writeAndFlush(result);
                }
            } catch (Exception e) {
                log.error("【主链路】解析协议出错:" + msg.toHexString(), e);
                e.printStackTrace();
            }

        }

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.warn("【主链路】channel读取异常:" + cause.getMessage(), cause);
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        log.info("---------【主链路心跳检测机制】触发------");
        if (evt instanceof IdleStateEvent) {
            if (((IdleStateEvent) evt).state() == IdleState.READER_IDLE) {
                log.warn("【主链路心跳检测机制】已经连续三分钟没收到下级平台的请求，关闭这个不活跃连接...");
                ctx.channel().close().sync();
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }
}
